package cn.harperDog.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author hua
 * @description
 * @date 2022/3/6
 * <p>
 * 实现一个方法
 * public static Object execute(String className, String methodName, Object args[])
 * 实现 “通过类的名字、方法名字、方法参数调调用方法，返回值为该方法的返回值。” 的功能。
 * <p>
 * 如果方法包含基本数据类型的入参，下面的写法就不适用了。
 * 完整的解决方案请看{@link InvokeMethodUltimate}
 */
public class InvokeMethodByReflect {
    public static Object execute(String className, String methodName, Object args[]) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        Class<?> clazz = Class.forName(className);
        Object obj = clazz.newInstance();

        Class<?>[] paramTypes = new Class[args.length];

        //获取参数类型
        for (int i = 0; i < args.length; i++) {
            paramTypes[i] = args[i].getClass();
        }

        Method method = clazz.getDeclaredMethod(methodName, paramTypes);
        method.setAccessible(true);
        return method.invoke(obj, args);
    }

    public static void main(String[] args) throws Exception {
        System.out.println(execute(A.class.getName(), "add", new Integer[]{1, 2}));
    }
}

class A {
    public int add(int a, int b) {
        return a + b;
    }

    public int raw() {
        return 1;
    }

    public String strInt(String str, int a) {
        return str + a;
    }
}